package com.families.service.impl;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.families.controller.LonginController;
import com.families.dao.LoginDao;
import com.families.dao.UserMapper;
import com.families.entity.User;
import com.families.service.LoginService;
import com.families.util.ModelUtil;

@Service("loginService")
public class LoginServiceImpl implements LoginService{
	private static final Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);
	@Autowired
	private LoginDao mdao;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	RedisTemplate<String, String> redisTemplate;
	@Value("${error.timeout}")
	private Integer timeout;
	

	public String login(User user) {
		// TODO Auto-generated method stub
		logger.info("---------------------------进入登录模块----------------------------------");
		String message = null;
		Subject currentUser = SecurityUtils.getSubject();
		if (!currentUser.isAuthenticated()) {//如果未认证
			    //传递用户名密码给shiro框架
	            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassWord());
	            token.setRememberMe(true); //记住我的登录状态
	            try {
	                currentUser.login(token);//认证
	                ValueOperations<String, String> forValue = redisTemplate.opsForValue();
	                forValue.set("SHIRO_LOGIN_COUNT"+user.getUserName(), "0");
	                
	                Session session=SecurityUtils.getSubject().getSession();
	     	        session.setAttribute("USER_SESSION", user);
	     	        message="登陆成功";
	                return message;
	            } catch (UnknownAccountException uae) {
	               System.out.println("该用户不存在: " + token.getPrincipal());
	               message="该用户不存在";
	               
	            } catch (IncorrectCredentialsException ice) {
	            	System.out.println("密码校验失败 :" + token.getPrincipal());
	            	message="密码校验失败";
	            	
	            } catch (LockedAccountException lae) {
	            	System.out.println("锁定账户,请联系管理员");
	            	message="锁定账户,请联系管理员";
	            	
	            }catch (DisabledAccountException eee) {
					// TODO: handle exception
	            	System.out.println("由于密码连续输错"+timeout+"次,账户锁定1分钟");
	            	message="由于密码连续输错"+timeout+"次,账户锁定1分钟";
	            	
				}catch (Exception ae) {
	                //unexpected condition?  error?
	            	logger.error("发生未知错误",ae);
	            	message="发生未知错误";
	            }
	           
	        }else {
	        	message="登陆成功";
			}
		
		return message;
	}

	public int sign(User user) {
		// TODO Auto-generated method stub
		logger.info("-----------------------------进入注册------------------------------");
		logger.info("请求状态：{}",JSON.toJSONString(user));
		String random=new SecureRandomNumberGenerator().nextBytes().toHex();
		logger.info("随机生成的盐：{}",random);
	    String pwd = new Md5Hash(user.getPassWord(),random,1).toString();
	    logger.info("加密过后的密码：{}",pwd);
		user.setPassWord(pwd);
		user.setSalt(random);
		user.setState(1);
		ModelUtil.setCommonFields(user);
		logger.info("插入数据:{}",JSON.toJSONString(user));
		int insert = userMapper.insert(user);
		return insert;
	}

	@Override
	public void logou() {
		// TODO Auto-generated method stub
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
	}

	public User signNameComparison(String userName) {
		logger.info("-------------------------------进入验证用户是否存在----------------------------");
		User byUserName = userMapper.getByUserName(userName);
		return byUserName;
	}

}
